# -*- coding: iso-8859-1 -*-
# file ODEObject.py
# author Rocco Martino
#
############################################################################
#    Copyright (C) 2015 by Rocco Martino                                   #
#    martinorocco@gmail.com                                                #
#                                                                          #
#    This program is free software; you can redistribute it and/or modify  #
#    it under the terms of the GNU Lesser General Public License as        #
#    published by the Free Software Foundation; either version 2.1 of the  #
#    License, or (at your option) any later version.                       #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU Lesser General Public License for more details.                   #
#                                                                          #
#    You should have received a copy of the GNU Lesser General Public      #
#    License along with this program; if not, write to the                 #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

############################################################################
from . import Object, Game
############################################################################




############################################################################
# ........................................................................ #
# ........................................................................ #
############################################################################




############################################################################
# ........................................................................ #
class ODEObject(Object.Object):





############################################################################
    UpdateCallback = None
############################################################################









############################################################################
    def __init__(self, obj, data):
        super(ODEObject, self).__init__(obj, data)

        self.ClassName = "osgODE::ODEObject"

        self.UpdateCallback = None
############################################################################




############################################################################
    def writeObject(self, writer):



        obj = self.BlenderObject

        if obj:
            self.Name = obj.name



        if self.Data.UseGame:
            try:
                for prop in self.BlenderObject.game.properties:

                    self.addUserValue( prop.name, prop.value )
            except:
                pass




            try:
                if ( len(self.BlenderObject.game.sensors) + len(self.BlenderObject.game.properties) ) > 0:
                    self.addUpdateCallback( Game.Game(self.BlenderObject, self.Data) )
            except:
                pass




        writer.moveIn(self.ClassName)



        if self.BlenderObject and self.CheckUniqueID:

            if self.BlenderObject in self.Data.ODEObjects:
                writer.writeLine( "UniqueID %d" % self.Data.ODEObjects[self.BlenderObject][0] )

            else:
                self.Data.ODEObjects[self.BlenderObject] = [self.Data.UniqueID.generate(), self]

                writer.writeLine( "UniqueID %d" % self.Data.ODEObjects[self.BlenderObject][0] )

                self.writeData( writer )

        else:

            writer.writeLine("UniqueID %d" % self.Data.UniqueID.generate())

            self.writeData( writer )



        writer.moveOut(self.ClassName)
############################################################################




############################################################################
    def writeData(self, writer):
        super(ODEObject, self).writeData(writer)

        writer.writeLine("ID %d" %self.Data.ooID.generate())



        if self.UpdateCallback:
            writer.moveIn("UpdateCallback TRUE")

            self.UpdateCallback.writeObject(writer) ;

            writer.moveOut("UpdateCallback TRUE")




        try:
            actor = self.BlenderObject.game.use_actor and self.BlenderObject.game.physics_type not in ["NO_COLLISION"]

            actor_radius = self.BlenderObject.game.radius
            actor_position, quaternion, scale = self.BlenderObject.matrix_local.decompose()

            writer.writeLine("ActorBound %f %f %f %f" % (actor_position[0], actor_position[1], actor_position[2], actor_radius))

            if actor:
                writer.writeLine("Actor TRUE")
            else:
                writer.writeLine("Actor FALSE")

        except:
            pass
############################################################################




############################################################################
    def addUpdateCallback(self, cbk):
        if not self.UpdateCallback:
            self.UpdateCallback = cbk
        else:
            self.UpdateCallback.addNestedCallback(cbk)
############################################################################




# ........................................................................ #
############################################################################









############################################################################
# ........................................................................ #
def createObject( obj, data ):

    from . import Transformable, RigidBody, Collidable, Container


    if obj.type in ["MESH", "EMPTY"]:


        is_dynamic = False

        try:
            is_dynamic = obj.material_slots[0].material.game_settings.physics
        except:
            is_dynamic = obj.type == "EMPTY"


        if not is_dynamic:
            return None



        is_container = False

        for i in obj.children:
            try:
                is_container = i.material_slots[0].material.game_settings.physics
            except:
                is_container = False

            if is_container:
                break



        if False:
            pass



        elif is_container:
            return Container.Container( obj, data )



        elif obj.game.physics_type in ["NO_COLLISION", "SENSOR"]:
            return Transformable.Transformable( obj, data )



        elif obj.game.physics_type in ["STATIC", "DYNAMIC", "RIGID_BODY"]:

            if not obj.game.use_collision_bounds:
                return RigidBody.RigidBody( obj, data )

            else:
                return Collidable.Collidable( obj, data )


    return None
# ........................................................................ #
############################################################################
